package com.bytecodezz.app.photoshop.loader.core

import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.net.Uri
import android.widget.ImageView
import androidx.fragment.app.Fragment
import com.bytecodezz.app.photoshop.loader.base.IPhotoshopLoaderBuilder
import com.bytecodezz.app.photoshop.loader.base.IPhotoshopLoaderTemplate
import com.bytecodezz.app.photoshop.loader.base.ModelTypes
import com.bytecodezz.app.photoshop.loader.listener.BitmapLoaderListener
import com.bytecodezz.app.photoshop.loader.listener.DrawableLoaderListener
import com.bytecodezz.app.photoshop.loader.listener.FileLoaderListener
import java.io.File

/**
 * 使用享元模式建立对象共享池
 * 接口 IPhotoshopLoaderBuilder 提供基本元素
 * 接口 ModelTypes 提供基本加载类型 起始
 * 接口 IPhotoshopLoaderTemplate 提供基本构建功能
 */
class LoaderBuilder : IPhotoshopLoaderBuilder(),
    IPhotoshopLoaderTemplate<LoaderBuilder>,
    ModelTypes<LoaderBuilder> {
    private var next: LoaderBuilder? = null

    companion object {
        private val sPoolSync = Any() //仅用于同步的锁
        private var sPool: LoaderBuilder? = null
        private var sPoolSize = 0
        private const val MAX_POOL_SIZE = 10 //最大缓存数

        /**
         * 创建Builder对象
         */
        fun obtain(): LoaderBuilder {
            synchronized(sPoolSync) {
                sPool?.let {
                    val builder: LoaderBuilder = it
                    sPool = builder.next
                    builder.next = null
                    sPoolSize--
                    return builder
                }
            }
            return LoaderBuilder()
        }
    }

    /**
     * 回收builder对象
     */
    override fun recycleUnchecked() {
        super.recycleUnchecked()
        synchronized(sPoolSync) {
            if (sPoolSize < MAX_POOL_SIZE) {
                next = sPool
                sPool = this
                sPoolSize++
            }
        }
    }

    fun with(
        activity: Activity? = null,
        fragment: Fragment? = null,
        context: Context? = null
    ): LoaderBuilder {
        this.activity = activity
        this.fragment = fragment
        this.context = context
        return this
    }

    override fun load(bitmap: Bitmap): LoaderBuilder {
        this.bitmap = bitmap
        return this
    }

    override fun load(drawable: Drawable): LoaderBuilder {
        this.drawable = drawable
        return this
    }

    override fun load(url: String): LoaderBuilder {
        this.url = url
        return this
    }

    override fun load(uri: Uri): LoaderBuilder {
        this.uri = uri
        return this
    }

    override fun load(file: File): LoaderBuilder {
        this.file = file
        return this
    }

    override fun load(resourceId: Int): LoaderBuilder {
        this.resourceId = resourceId
        return this
    }

    override fun load(model: ByteArray): LoaderBuilder {
        this.byteArray = model
        return this
    }

    override fun downloadOnly(): LoaderBuilder {
        this.isOnlyDownload = true
        return this
    }

    override fun asBitmap(): LoaderBuilder {
        this.isBitmap = true
        return this
    }

    override fun asDrawable(): LoaderBuilder {
        this.isDrawable = true
        return this
    }

    override fun asFile(): LoaderBuilder {
        this.isFile = true
        return this
    }

    override fun asGif(): LoaderBuilder {
        this.isGif = true
        return this
    }

    override fun error(bitmap: Bitmap): LoaderBuilder {
        this.errorBitmap = bitmap
        return this
    }

    override fun error(drawable: Drawable): LoaderBuilder {
        this.errorDrawable = drawable
        return this
    }

    override fun error(resourceId: Int): LoaderBuilder {
        this.errorResourceId = resourceId
        return this
    }

    override fun preload(width: Int, height: Int): LoaderBuilder {
        this.preWidth = width
        this.preHeight = height
        return this
    }

    override fun into(imageView: ImageView) {
        this.imageView = imageView
        startHandler()
    }

    override fun into() {
        startHandler()
    }

    private fun startHandler() {
        PhotoshopLoaderManager.get().startLoader(this)
    }

    override fun addListener(listener: BitmapLoaderListener): LoaderBuilder {
        this.bitmapListener = listener
        return this
    }

    override fun addListener(listener: FileLoaderListener): LoaderBuilder {
        this.fileListener = listener
        return this
    }

    override fun addListener(listener: DrawableLoaderListener): LoaderBuilder {
        this.drawableListener = listener
        return this
    }

}